#include <stdio.h>
#include <unistd.h>

#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_gpio.h"
#include "hi_io.h"

// 定义控制LED的GPIO引脚编号为9
#define LED_TASK_GPIO 6
// 定义控制按键的GPIO引脚编号为5
#define BUTTON_TASK_GPIO 14

// 定义LED闪烁间隔时间为30个ticks
#define LED_INTERVAL_TIME 30
// 定义任务的堆栈大小为512字节
#define LED_TASK_STACK_SIZE 512
// 定义任务的优先级为25
#define LED_TASK_PRIO 25

 // 定义三色灯LED连接的 GPIO 引脚编号
 #define RED_LED_PIN_NAME 2
 #define G_LED_PIN_NAME 8
 #define B_LED_PIN_NAME 7
 // 定义PWM占空比的最大值
 #define IOT_PWM_DUTY_MAX  100
 // 定义PWM频率分频系数
 #define PWM_FREQ_DIVITION 64000
 // 定义延时时间（微秒）
 #define DELAY_US 250000
 // 定义倍增因子
 #define DOUBLE  (2)




// 定义LED状态枚举类型
enum LedState
{
    R = 0,     // LED处于打开状态
    G,        // LED处于关闭状态
    B,      // LED处于闪烁状态
};

// 初始化全局变量g_ledState为闪烁状态
enum LedState g_ledState = R;

// LED任务函数，用于控制LED的行为
static void LedTask()
{
    while (1) // 进入无限循环，持续监控和更新LED状态
    {
        
        switch (g_ledState) // 根据全局变量g_ledState的值执行不同的操作
        {
        case R: // 如果当前状态是LED_ON
            // 将红色LED引脚设置为PWM输出模式
            hi_io_set_func(RED_LED_PIN_NAME, HI_IO_FUNC_GPIO_10_PWM1_OUT);
            // 初始化PWM模块
            IoTPwmInit(2);
            // 使用PWM控制红色LED亮度
            for (int i = 1; i < IOT_PWM_DUTY_MAX; i *= DOUBLE) {
                // 启动PWM，设置占空比为i，频率分频系数为PWM_FREQ_DIVITION
                IoTPwmStart(2, i, PWM_FREQ_DIVITION);
                // 延时DELAY_US微秒
                usleep(DELAY_US);
                // 停止PWM
                IoTPwmStop(2);
            }            
            break;
        case G: // 如果当前状态是LED_OFF
            // 将绿色LED引脚设置为PWM输出模式
            hi_io_set_func(G_LED_PIN_NAME, HI_IO_FUNC_GPIO_10_PWM1_OUT);
            // 初始化PWM模块
            IoTPwmInit(1);
            for (int i = 1; i < IOT_PWM_DUTY_MAX; i *= DOUBLE) {
                // 启动PWM，设置占空比为i，频率分频系数为PWM_FREQ_DIVITION
                IoTPwmStart(1, i, PWM_FREQ_DIVITION);
                // 延时DELAY_US微秒
                usleep(DELAY_US);
                // 停止PWM
                IoTPwmStop(1);
            }
            break;
        case B: // 如果当前状态是LED_SPARK
            // 将蓝色LED引脚设置为PWM输出模式
            hi_io_set_func(B_LED_PIN_NAME, HI_IO_FUNC_GPIO_10_PWM1_OUT);
            // 初始化PWM模块
            IoTPwmInit(0);
            for (int i = 1; i < IOT_PWM_DUTY_MAX; i *= DOUBLE) {
                // 启动PWM，设置占空比为i，频率分频系数为PWM_FREQ_DIVITION
                IoTPwmStart(0, i, PWM_FREQ_DIVITION);
                // 延时DELAY_US微秒
                usleep(DELAY_US);
                // 停止PWM
                IoTPwmStop(0);
            }
            break;
        }
    }
}

// 按键按下处理函数，用于切换LED状态
static void OnButtonPressed()
{
    static int cnt = 0; // 定义一个静态计数器cnt，用于记录按键按下的次数（在本例中未实际使用）
    enum LedState nextState = R; // 初始化下一个状态为LED_SPARK

    // 根据当前的g_ledState确定下一个状态nextState
    switch (g_ledState)
    {
    case R: // 如果当前状态是LED_ON
        nextState = G; // 切换到LED_OFF
        break;
    case G: // 如果当前状态是LED_OFF
        nextState = B; // 切换到LED_ON
        break;
    case B: // 如果当前状态是LED_SPARK
        nextState = R; // 切换到LED_OFF
        break;
    default:
        break;
    }

    g_ledState = nextState; // 将全局变量g_ledState更新为nextState，从而改变LED的行为
}

// 主任务入口函数，用于初始化GPIO、创建任务和注册中断处理函数
static void LedExampleEntry(void)
{
 
    // 初始化红色LED引脚
    IoTGpioInit(RED_LED_PIN_NAME);
    // 按键GPIO5初始化
    IoTGpioInit(BUTTON_TASK_GPIO);

    // 模式设置为标准GPIO
    hi_io_set_func(BUTTON_TASK_GPIO, HI_IO_FUNC_GPIO_14_GPIO);
    // 设置为输入模式
    IoTGpioSetDir(BUTTON_TASK_GPIO, IOT_GPIO_DIR_IN);
    // 拉高GPIO5电平等待后续按键事件触发
    hi_io_set_pull(BUTTON_TASK_GPIO, HI_IO_PULL_UP);
    // 注册按键中断处理函数，当检测到上升沿或高电平时调用OnButtonPressed函数
    IoTGpioRegisterIsrFunc(BUTTON_TASK_GPIO, IOT_INT_TYPE_EDGE, IOT_GPIO_EDGE_RISE_LEVEL_HIGH, OnButtonPressed, NULL);

    // 配置任务属性
    osThreadAttr_t attr;

    attr.name = "LedTask"; // 设置任务名称为"LedTask"
    attr.attr_bits = 0U; // 设置任务属性位掩码，默认为0
    attr.cb_mem = NULL; // 回调内存，默认为空
    attr.cb_size = 0U; // 回调内存大小，默认为0
    attr.stack_mem = NULL; // 堆栈内存，默认为空
    attr.stack_size = LED_TASK_STACK_SIZE; // 设置堆栈大小为LED_TASK_STACK_SIZE
    attr.priority = LED_TASK_PRIO; // 设置任务优先级为LED_TASK_PRIO

    // 创建任务LedTask，检查创建是否成功
    if (osThreadNew((osThreadFunc_t)LedTask, NULL, &attr) == NULL)
    {
        printf("[LedExample] Failed to create LedTask!\n"); // 如果创建失败，输出错误信息
    }
}

// 注册初始化函数LedExampleEntry，当系统启动时会自动调用这个函数来执行任务创建和GPIO控制的相关操作
SYS_RUN(LedExampleEntry);